package cn.antcore.common.config;

import cn.antcore.common.security.handler.GoAuthenticationLoginFailureHandler;
import cn.antcore.common.security.handler.GoAuthenticationLoginSuccessHandler;
import cn.antcore.common.security.handler.GoAuthenticationLogoutSuccessHandler;
import cn.antcore.common.security.mobile.MobileLoginConfigurer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

/**
 * SpringSecurity配置
 * <br>
 * Created by Hong 2024/5/28
**/
@Configuration
public class WebSecurityConfiguration {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public WebSecurityCustomizer ignoringCustomizer() {
        return (web) -> web.ignoring().requestMatchers("/test");
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, MobileLoginConfigurer mobileLoginConfigurer, ObjectMapper objectMapper) throws Exception {
        // 应用手机验证码登录配置
        http.apply(mobileLoginConfigurer);
        http.authorizeHttpRequests(auth -> auth.requestMatchers("/file/*").permitAll()
                .anyRequest().authenticated()
        );

        // 登录配置
        http.formLogin((form) -> form.loginPage("/login")
                .successHandler(new GoAuthenticationLoginSuccessHandler(objectMapper))
                .failureHandler(new GoAuthenticationLoginFailureHandler(objectMapper))
                .permitAll());

        // 退出登录配置
        http.logout((logout) -> logout.logoutSuccessHandler(new GoAuthenticationLogoutSuccessHandler(objectMapper)));
        http.csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }
}
